import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Message } from './entities/message.entity';
import { CreateMessageDto } from './dto/create-message.dto';
import { QueryMessageDto } from './dto/query-message.dto';

@Injectable()
export class MessageService {
  @InjectRepository(Message)
  private messageRepository: Repository<Message>;

  async create(createMessageDto: CreateMessageDto, userId: number) {
    const { title, content, type, toUserId } = createMessageDto;

    const message = new Message();
    message.title = title;
    message.content = content;
    message.type = type;
    message.user = { id: toUserId || userId } as any;

    if (type === 3 && toUserId) {
      // 聊天消息需要记录发送者
      message.fromUser = { id: userId } as any;
    }

    try {
      await this.messageRepository.save(message);
      return '发送成功';
    } catch (e) {
      throw new HttpException('发送失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async findAll(queryMessageDto: QueryMessageDto, userId: number) {
    const {
      pageNum = 1,
      pageSize = 10,
      type,
      unreadOnly,
      fromUserId,
    } = queryMessageDto;

    const skipCount = (pageNum - 1) * pageSize;
    const condition: Record<string, any> = {
      user: { id: userId },
    };

    if (type) {
      condition.type = type;
    }
    if (unreadOnly) {
      condition.isRead = false;
    }
    if (fromUserId) {
      condition.fromUser = { id: fromUserId };
    }

    const [messages, total] = await this.messageRepository.findAndCount({
      where: condition,
      skip: skipCount,
      take: pageSize,
      relations: ['fromUser'],
      order: {
        createTime: 'DESC',
      },
    });

    return {
      messages,
      total,
    };
  }

  async getUnreadCount(userId: number) {
    const count = await this.messageRepository.count({
      where: {
        user: { id: userId },
        isRead: false,
      },
    });

    return {
      count,
    };
  }

  async markAsRead(id: number, userId: number) {
    const message = await this.messageRepository.findOne({
      where: { id, user: { id: userId } },
    });

    if (!message) {
      throw new HttpException('消息不存在', HttpStatus.BAD_REQUEST);
    }

    if (message.isRead) {
      return '消息已读';
    }

    message.isRead = true;

    try {
      await this.messageRepository.save(message);
      return '标记成功';
    } catch (e) {
      throw new HttpException('标记失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async markAllAsRead(userId: number) {
    try {
      await this.messageRepository.update(
        { user: { id: userId }, isRead: false },
        { isRead: true },
      );
      return '标记成功';
    } catch (e) {
      throw new HttpException('标记失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
